﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using IBNet.UtilsDataStructuresAndExtensions;
using IBNet;
using System.Threading;
using System.Collections;
using System.Diagnostics;

namespace IBNet.DayTrade
{
   public partial class DayTradeMainForm : Form, IWrapDayTradeMainForm
   {
      static readonly string[] _initialBarsReceivedAndTradesAndLastPrice
         = new string[3] { "0", "0", "0" };

      private void RequestRealTimeBars(Contract contract, int numberOfPriceBarsToStore, 
         RealTimeBarSeconds secondsPerPriceBar, IList<Indicator> indicators, 
         TradingHours tradingHours)
      {
         int requestId = Interlocked.Increment(ref _currentRequestId);
         bool useRth = (tradingHours == TradingHours.RegularHours) ? true : false;
         RealTimeBarType realTimeBarType = (contract.SecurityType == SecurityType.Cash) ?
            RealTimeBarType.Midpoint : RealTimeBarType.Trades;

         PriceBarsAndIndicatorValues priceBarsAndIndicatorValues = 
            new PriceBarsAndIndicatorValues(contract, numberOfPriceBarsToStore, 
               secondsPerPriceBar, indicators);

         _requestIdToPriceBarsAndIndicatorValues.Add(requestId, 
            priceBarsAndIndicatorValues);
         _symbolToUnsubscribeRequestId.Add(contract.FullSymbol, requestId);
         ibClient.RegisterRealTimeBarRequestIdForMultithreading(requestId);

         listViewRealTimeBarSubscriptions.Insert(contract.FullSymbol,
            contract.FullSymbol, InvocationMethod.Invoke,
            _initialBarsReceivedAndTradesAndLastPrice);

         ibClient.RequestRealTimeBars(requestId, contract, realTimeBarType, useRth);
      }

      private IEnumerable<Contract> MakeContractsFromSymbols(IList<string> symbols)
      {
         foreach (string symbol in symbols)
         {
            string symbolUpper = symbol.ToUpper();

            if (symbolUpper.Contains("."))
            // Then symbol is a Forex symbol. Example: EUR.USD
            {
               string[] symbolAndCurrency = symbolUpper.Split(new char[] { '.' });
               string forexSymbol = symbolAndCurrency[0];
               string currency = symbolAndCurrency[1];
               Forex forexContractToTrade = new Forex(forexSymbol, currency);
               yield return forexContractToTrade;
            }
            else
            // Symbol is a Stock symbol
            {
               Stock stockContractToTrade = new Stock(symbolUpper);
               yield return stockContractToTrade;
            }
         }
      }

      private void RegisterOrderAndContractForDayTrading(OrderAndContract orderAndContract)
      {
         _orderIdToOrderAndContract.Add(orderAndContract.Order.OrderId, orderAndContract);
         _openingOrderIds.Add(orderAndContract.OrderId);
         _symbolsWithOpenDaytradeOrders.Add(orderAndContract.FullSymbol);
      }

      private void DeregisterOrderAndContractFromDayTrading(OrderAndContract orderAndContract)
      {
         _orderIdToOrderAndContract.Remove(orderAndContract.OrderId);
         _openingOrderIds.Remove(orderAndContract.OrderId);
         _symbolsWithOpenDaytradeOrders.Remove(orderAndContract.FullSymbol);
      }
   }
}
